Skip to content

Fix nextflow lint ignoring --quiet flag#6880

Open
ewels wants to merge 7 commits intomasterfrom
claude/fix-nextflow-6856-kFl6g
Open

Fix nextflow lint ignoring --quiet flag#6880
ewels wants to merge 7 commits intomasterfrom
claude/fix-nextflow-6856-kFl6g

Conversation

@ewels
Copy link
Member

@ewels ewels commented Mar 2, 2026

nextflow lint ignores the --quiet (-q) flag. The StandardErrorListener class writes progress messages directly to AnsiConsole.out, bypassing Nextflow’s logger infrastructure which respects the -q flag.

This PR fixes that. Closes #6856

The StandardErrorListener used AnsiConsole.out directly to print
progress messages, bypassing Nextflow's logger which respects the
`-q` flag. Add a `quiet` parameter to StandardErrorListener that
suppresses progress output (beforeAll, beforeFile, beforeFormat,
afterAll) while still showing errors and warnings.

Signed-off-by: nextflow-io <info@nextflow.io>

https://claude.ai/code/session_01MY4FcPPaSmACrBsdpHTfnT
Signed-off-by: Claude <noreply@anthropic.com>
@netlify
Copy link

netlify bot commented Mar 2, 2026

Deploy Preview for nextflow-docs-staging canceled.

Name Link
🔨 Latest commit b0d42f2
🔍 Latest deploy log https://app.netlify.com/projects/nextflow-docs-staging/deploys/69a702167dc6420008e3eccf

@ewels ewels force-pushed the claude/fix-nextflow-6856-kFl6g branch from 74b4029 to 183ae1e Compare March 3, 2026 07:57
Two issues were causing test failures:

1. StandardErrorListener was printing via AnsiConsole.out, which is a
   static field initialized at class-load time and not updated when
   OutputCapture replaces System.out. Switch all output to System.out
   so test capture works correctly.

2. CmdLint is @CompileStatic, so the Groovy compiler generates a call
   to isQuiet() (boolean convention) rather than getQuiet() when
   accessing launcher.options.quiet. The test stubs were using
   getQuiet() >> true, which was never called, so quiet was always
   false. Fix by stubbing isQuiet() >> true instead.

Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
@ewels

This comment was marked as outdated.

Introduce a private print() helper that consolidates all output via a
single code path:

- When ansiLog=true, delegates to AnsiConsole.out, which handles TTY
  detection and strips ANSI escape codes when writing to a pipe.
- When ansiLog=false, sets Ansi.setEnabled(false) immediately before
  rendering the Ansi object to plain text, then writes to System.out.
  Setting the flag just before toString() ensures the global Ansi state
  is correct at render time regardless of what other components may have
  set in between. Writing to System.out (rather than the static
  AnsiConsole.out field) means the output is captured correctly by test
  infrastructure that replaces System.out.

Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
@ewels

This comment was marked as outdated.

Ansi.setEnabled() is static-only in Jansi 2.x -- there is no per-instance
flag. Ansi.toString() returns the raw StringBuilder contents; escape codes
are baked in when fg()/bold() etc. are called, not at render time.

The previous approach of calling Ansi.setEnabled(false) in print() just
before toString() was too late: codes were already in the buffer.

Fix: call Ansi.setEnabled(ansiLog) inside the ansi() helper, before every
Ansi object is created. This ensures the global flag is correct for all
subsequent append operations, so plain-text output is produced when
ansiLog=false (e.g. when writing to a pipe in integration tests).

Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
@ewels
Copy link
Member Author

ewels commented Mar 3, 2026

Further fix: ANSI code stripping

After more investigation, the previous approach of calling Ansi.setEnabled(false) in the print() helper just before toString() was also incorrect.

Root cause: Ansi.setEnabled() is static-only in Jansi 2.4.2 — there is no per-instance enabled flag. More importantly, Ansi.toString() returns the raw StringBuilder contents without any stripping at render time. Escape codes are baked into the buffer when fg(), bold(), etc. are called — not when toString() is invoked.

So calling setEnabled(false) just before toString() was already too late: the codes were already in the buffer from when onError() built up term.

Fix: move Ansi.setEnabled(ansiLog) into the ansi() helper, so the global flag is set correctly before every Ansi object is created and before any fg()/bold() calls run. This ensures no escape codes are appended to the buffer when ansiLog=false (e.g. when writing to a pipe in the integration tests).

ewels added 3 commits March 3, 2026 16:23
- StandardErrorListener now suppresses progress messages (file-by-file
  status and final summary) when ansiLog=false, i.e. when running with
  -no-ansi or NXF_ANSI_LOG=false.  The animated progress lines rely on
  cursor-up/erase-line ANSI sequences and are meaningless in
  non-interactive/piped output.

- Add a -q/-quiet flag to 'nextflow lint' that suppresses progress
  messages at the lint-command level.  Unlike the global --quiet flag
  this does not disable ANSI colours, so error output still benefits
  from colour highlighting when the terminal supports it.

- Rename the internal 'quiet' flag to 'suppressProgress' to better
  reflect its purpose (errors are always shown; only status messages
  are suppressed).

Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
The final 'Nextflow linting complete!' summary is now always printed,
even when progress is suppressed (--quiet / -q / non-interactive output).
Only the per-file 'Linting: ...' status lines are suppressed.

Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
@ewels
Copy link
Member Author

ewels commented Mar 3, 2026

Ok I updated it so that there is now some slightly differing behaviour, but hopefully gives the functionality we want:

  • NXF_ANSI_LOG=0 now does not print the "Linting .." status updates
  • nextflow -q lint is effectively identical, it disables ANSI logging at the top level so no colour
  • I wanted to be able to have not-verbose-but-still-colours, so I added nextflow lint -q which does have ANSI logging with colours, but does not have the "Linting " status updates.

We could simplify this further by simply removing the "Linting " updates entirely as they give fairly limited functionality (just saying that something is happening). Happy to do that if you prefer @bentsherman

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

nextflow lint ignores --quiet flag

2 participants